package bancosys.tec.rtm.impl.diagnostician;

import static bancosys.tec.rtm.diagnostician.AbstractDiagnostician.JMX_DEFAULT_CACHE_DURATION_IN_SECONDS;
import static bancosys.tec.rtm.diagnostician.AbstractDiagnostician.JMX_NAMESPACE;
import static bancosys.tec.rtm.impl.diagnostician.SystemUpTimeDiagnostician.NAME;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;

import bancosys.tec.rtm.diagnostician.AbstractDiagnostician;
import bancosys.tec.rtm.diagnostician.DiagnosisBean;

/**
 * Diagnosticador que produz dados de quanto tempo o sistema está startado rodando no servidor.
 * 
 * @author Evaristo
 */
@ManagedResource(description = NAME, objectName = JMX_NAMESPACE + ":name=systemUpTime", currencyTimeLimit = JMX_DEFAULT_CACHE_DURATION_IN_SECONDS)
public class SystemUpTimeDiagnostician extends AbstractDiagnostician {

    public static final String NAME = "UpTime";

    private static final long SEGUNDO = 1000;

    private static final long MINUTO = SEGUNDO * 60;

    private static final long HORA = MINUTO * 60;

    private static final long DIA = HORA * 24;

    private static final String KEY_UPTIME = "uptime";

    private Date systemStartDate;

    /**
     * Construtor.
     */
    public SystemUpTimeDiagnostician() {
        this.systemStartDate = new Date();
    }

    /**
     * Construtor.
     * 
     * @param systemStartDate data de inicialização do sistema.
     */
    public SystemUpTimeDiagnostician(Date systemStartDate) {
        this.systemStartDate = systemStartDate;
    }

    /**
     * {@inheritDoc}
     */
    public String getName() {
        return NAME;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected boolean fillDiagnosisBean(DiagnosisBean bean) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
        String dataFormatada = format.format(this.systemStartDate);
        bean.addDescription("Data/Hora do Start do Sistema: " + dataFormatada);

        Calendar dataStartSistema = new GregorianCalendar();
        dataStartSistema.setTime(this.systemStartDate);
        Calendar dataAtual = new GregorianCalendar();

        long dataAtualMillis = dataAtual.getTimeInMillis();
        long dataStartSistemaMillis = dataStartSistema.getTimeInMillis();

        long tempoNoArMillis = dataAtualMillis - dataStartSistemaMillis;
        bean.putValue(KEY_UPTIME, tempoNoArMillis);

        bean.addDescription("Tempo de Permanência do Sistema Ativo: ");

        long diasNoAr = tempoNoArMillis / DIA;
        if (diasNoAr != 0) {
            bean.addDescription("    Dias: " + diasNoAr);
            tempoNoArMillis = tempoNoArMillis % DIA;
        }

        long horasNoAr = tempoNoArMillis / HORA;
        if (horasNoAr != 0) {
            bean.addDescription("    Horas: " + horasNoAr);
            tempoNoArMillis = tempoNoArMillis % HORA;
        }

        long minutosNoAr = tempoNoArMillis / MINUTO;
        if (minutosNoAr != 0) {
            bean.addDescription("    Minutos: " + minutosNoAr);
            tempoNoArMillis = tempoNoArMillis % MINUTO;
        }

        long segundosNoAr = tempoNoArMillis / SEGUNDO;
        if (segundosNoAr != 0) {
            bean.addDescription("    Segundos: " + segundosNoAr);
        }
        return true;
    }

    /**
     * @return uptime.
     */
    @ManagedAttribute(description = KEY_UPTIME)
    public Long getUptime() {
        return (Long) this.getValue(KEY_UPTIME);
    }
}